#ifndef GRID_GROUND_FILTER_HPP_
#define GRID_GROUND_FILTER_HPP_

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/PointIndices.h>

#include <memory>

namespace autoware_ground_segmentation
{

/**
 * @brief Grid-based ground filtering for point clouds
 * 
 * This class provides grid-based approaches for ground segmentation:
 * - Regular grid processing
 * - Elevation grid processing with height-based classification
 */
class GridGroundFilter
{
public:
  GridGroundFilter();
  ~GridGroundFilter();

  /**
   * @brief Set grid processing parameters
   * @param grid_size Grid cell size in meters
   * @param switch_radius Radius to switch grid modes
   * @param buffer_size Number of ground points to keep per grid cell
   * @param lidar_z Virtual lidar height
   */
  void setParameters(float grid_size, float switch_radius, uint16_t buffer_size, float lidar_z);

  /**
   * @brief Process point cloud using regular grid approach
   * @param input_cloud Input point cloud
   * @param ground_indices Output indices of ground points
   * @param no_ground_indices Output indices of non-ground points
   */
  void processGrid(
    const pcl::PointCloud<pcl::PointXYZ>::Ptr& input_cloud,
    pcl::PointIndices& ground_indices,
    pcl::PointIndices& no_ground_indices);

  /**
   * @brief Process point cloud using elevation grid approach
   * @param input_cloud Input point cloud
   * @param ground_indices Output indices of ground points
   * @param no_ground_indices Output indices of non-ground points
   */
  void processElevationGrid(
    const pcl::PointCloud<pcl::PointXYZ>::Ptr& input_cloud,
    pcl::PointIndices& ground_indices,
    pcl::PointIndices& no_ground_indices);

private:
  float grid_size_m_;
  float grid_mode_switch_radius_;
  uint16_t gnd_grid_buffer_size_;
  float virtual_lidar_z_;
};

} // namespace autoware_ground_segmentation

#endif // GRID_GROUND_FILTER_HPP_ 